From 83b44e251e97cdc39c046ca75a9b24bdfcd53402 Mon Sep 17 00:00:00 2001 From: "iap10@labyrinth.cl.cam.ac.uk" Date: Mon, 16 Aug 2004 16:55:28 +0000 Subject: [PATCH] bitkeeper revision 1.1159.33.1 (4120e700LNXbe5IhAOotAN5jyP0RJw) suspend/resume fixes --- .../drivers/xen/netfront/netfront.c | 20 ++++++-- .../include/asm-xen/hypervisor.h | 3 +- tools/libxc/xc_linux_restore.c | 48 +++++++++++++++++++ tools/libxc/xc_linux_save.c | 42 +++++++++++++--- tools/libxc/xc_private.h | 36 ++++++++++++++ xen/common/dom_mem_ops.c | 31 +++++++++--- 6 files changed, 163 insertions(+), 17 deletions(-) diff --git a/linux-2.6.7-xen-sparse/drivers/xen/netfront/netfront.c b/linux-2.6.7-xen-sparse/drivers/xen/netfront/netfront.c index 7a9cfed29e..42f7830c87 100644 --- a/linux-2.6.7-xen-sparse/drivers/xen/netfront/netfront.c +++ b/linux-2.6.7-xen-sparse/drivers/xen/netfront/netfront.c @@ -17,6 +17,7 @@ #include #include #include +#include #include #include #include @@ -427,9 +428,7 @@ static int netif_poll(struct net_device *dev, int *pbudget) */ if ( unlikely(rx->status <= 0) ) { - /* Gate this error. We get a (valid) slew of them on suspend. */ - if ( np->user_state == UST_OPEN ) - printk(KERN_ALERT "bad buffer on RX ring!(%d)\n", rx->status); + printk(KERN_ALERT "bad buffer on RX ring!(%d)\n", rx->status); np->rx->ring[MASK_NETIF_RX_IDX(np->rx->req_prod)].req.id = rx->id; wmb(); np->rx->req_prod++; @@ -470,6 +469,15 @@ static int netif_poll(struct net_device *dev, int *pbudget) mcl->args[2] = 0; mcl++; (void)HYPERVISOR_multicall(rx_mcl, mcl - rx_mcl); + +#if 0 + if (unlikely(rx_mcl[0].args[5] != 0)) + printk(KERN_ALERT"Hypercall0 failed %u\n",np->rx->resp_prod); + + if (unlikely(rx_mcl[1].args[5] != 0)) + printk(KERN_ALERT"Hypercall1 failed %u\n",np->rx->resp_prod); +#endif + } while ( (skb = __skb_dequeue(&rxq)) != NULL ) @@ -595,6 +603,7 @@ static void network_connect(struct net_device *dev, printk(KERN_ALERT"Netfront recovered tx=%d rxfree=%d\n", np->tx->req_prod,np->rx->req_prod); + /* Step 3: All public and private state should now be sane. Get * ready to start sending and receiving packets and give the driver * domain a kick because we've probably just requeued some @@ -916,6 +925,8 @@ void netif_resume(void) struct net_private *np = NULL; int i; + + #if 1 /* XXX THIS IS TEMPORARY */ @@ -932,6 +943,9 @@ void netif_resume(void) // stop bad things from happening until we're back up np->backend_state = BEST_DISCONNECTED; + + memset(np->tx,0,PAGE_SIZE); + memset(np->rx,0,PAGE_SIZE); cmsg.type = CMSG_NETIF_FE; cmsg.subtype = CMSG_NETIF_FE_INTERFACE_CONNECT; diff --git a/linux-2.6.7-xen-sparse/include/asm-xen/hypervisor.h b/linux-2.6.7-xen-sparse/include/asm-xen/hypervisor.h index 5b89913a81..611252cc84 100644 --- a/linux-2.6.7-xen-sparse/include/asm-xen/hypervisor.h +++ b/linux-2.6.7-xen-sparse/include/asm-xen/hypervisor.h @@ -374,7 +374,8 @@ static inline int HYPERVISOR_dom_mem_op(unsigned int op, __asm__ __volatile__ ( TRAP_INSTR : "=a" (ret) : "0" (__HYPERVISOR_dom_mem_op), - "b" (op), "c" (extent_list), "d" (nr_extents), "S" (extent_order) + "b" (op), "c" (extent_list), "d" (nr_extents), "S" (extent_order), + "D" (DOMID_SELF) : "memory" ); return ret; diff --git a/tools/libxc/xc_linux_restore.c b/tools/libxc/xc_linux_restore.c index 0c1ca91ffc..513e838a38 100644 --- a/tools/libxc/xc_linux_restore.c +++ b/tools/libxc/xc_linux_restore.c @@ -504,6 +504,54 @@ printf("XXXXXXXXXXXXXXX pin L2\n"); xcio_info(ioctxt, "\b\b\b\b100%%\nMemory reloaded.\n"); + /* Get the list of PFNs that are not in the psuedo-phys map */ + { + unsigned int count, *pfntab; + int rc; + if ( xcio_read(ioctxt, &count, sizeof(count)) ) + { + xcio_error(ioctxt, "Error when reading from state file"); + goto out; + } + + pfntab = malloc( sizeof(unsigned int) * count ); + if ( !pfntab ) + { + xcio_error(ioctxt, "Out of memory"); + goto out; + } + + if ( xcio_read(ioctxt, pfntab, sizeof(unsigned int)*count) ) + { + xcio_error(ioctxt, "Error when reading pfntab from state file"); + goto out; + } + + for(i=0;i0 ) + { + if ( (rc = do_dom_mem_op( xc_handle, + MEMOP_decrease_reservation, + pfntab, count, 0, dom )) <0 ) + { + xcio_error(ioctxt, "Could not decrease reservation : %d",rc); + goto out; + } + else + { + printf("Decreased reservation by %d pages\n", count); + } + } + + } + + if ( xcio_read(ioctxt, &ctxt, sizeof(ctxt)) || xcio_read(ioctxt, shared_info, PAGE_SIZE) ) diff --git a/tools/libxc/xc_linux_save.c b/tools/libxc/xc_linux_save.c index c3089955c9..5a47b30f56 100644 --- a/tools/libxc/xc_linux_save.c +++ b/tools/libxc/xc_linux_save.c @@ -463,10 +463,6 @@ int xc_linux_save(int xc_handle, XcIOContext *ioctxt) goto out; } - printf("SUSPPPPPPPP flags %08lx shinfo %08lx eip %08lx esi %08lx\n", - op.u.getdomaininfo.flags, op.u.getdomaininfo.shared_info_frame, - ctxt.cpu_ctxt.eip, ctxt.cpu_ctxt.esi ); - } /* calculate the power of 2 order of nr_pfns, e.g. @@ -866,9 +862,41 @@ printf("type fail: page %i mfn %08lx\n",j,pfn_type[j]); goto out; } -printf("SUSPPPPPPPP flags %08lx shinfo %08lx eip %08lx esi %08lx\n", - op.u.getdomaininfo.flags, op.u.getdomaininfo.shared_info_frame, - ctxt.cpu_ctxt.eip, ctxt.cpu_ctxt.esi ); + /* Send through a list of all the PFNs that were not in map at the close */ + { + unsigned int i,j; + unsigned int pfntab[1024]; + + for ( i = 0, j = 0; i < nr_pfns; i++ ) + { + if ( live_pfn_to_mfn_table[i] >= 0x80000000UL ) + j++; + } + + if ( xcio_write(ioctxt, &j, sizeof(unsigned int)) ) + { + xcio_error(ioctxt, "Error when writing to state file (6a)"); + goto out; + } + + for ( i = 0, j = 0; i < nr_pfns; ) + { + if ( live_pfn_to_mfn_table[i] >= 0x80000000UL ) + { + pfntab[j++] = i; + } + i++; + if ( j == 1024 || i == nr_pfns ) + { + if ( xcio_write(ioctxt, &pfntab, sizeof(unsigned long)*j) ) + { + xcio_error(ioctxt, "Error when writing to state file (6b)"); + goto out; + } + j = 0; + } + } + } /* Map the suspend-record MFN to pin it. The page must be owned by domid for this to succeed. */ diff --git a/tools/libxc/xc_private.h b/tools/libxc/xc_private.h index 3d0572501b..d70f7df58a 100644 --- a/tools/libxc/xc_private.h +++ b/tools/libxc/xc_private.h @@ -127,6 +127,42 @@ static inline int do_multicall_op(int xc_handle, out1: return ret; } + +static inline int do_dom_mem_op(int xc_handle, + unsigned int memop, + unsigned int *extent_list, + unsigned int nr_extents, + unsigned int extent_order, + domid_t domid) +{ + privcmd_hypercall_t hypercall; + long ret = -EINVAL; + + hypercall.op = __HYPERVISOR_dom_mem_op; + hypercall.arg[0] = (unsigned long)memop; + hypercall.arg[1] = (unsigned long)extent_list; + hypercall.arg[2] = (unsigned long)nr_extents; + hypercall.arg[3] = (unsigned long)extent_order; + hypercall.arg[4] = (unsigned long)domid; + + if ( mlock(extent_list, nr_extents*sizeof(unsigned long)) != 0 ) + { + PERROR("Could not lock memory for Xen hypercall"); + goto out1; + } + + if ( (ret = do_xen_hypercall(xc_handle, &hypercall)) < 0 ) + { + fprintf(stderr, "Dom_mem operation failed (rc=%ld errno=%d)-- need to" + " rebuild the user-space tool set?\n",ret,errno); + goto out2; + } + + out2: (void)munlock(extent_list, nr_extents*sizeof(unsigned long)); + out1: return ret; +} + + /* * PFN mapping. */ diff --git a/xen/common/dom_mem_ops.c b/xen/common/dom_mem_ops.c index e2a330ae96..027dc790ce 100644 --- a/xen/common/dom_mem_ops.c +++ b/xen/common/dom_mem_ops.c @@ -92,13 +92,32 @@ static long free_dom_mem(struct domain *d, long do_dom_mem_op(unsigned int op, unsigned long *extent_list, unsigned long nr_extents, - unsigned int extent_order) + unsigned int extent_order, + domid_t domid) { - if ( op == MEMOP_increase_reservation ) - return alloc_dom_mem(current, extent_list, nr_extents, extent_order); + struct domain *d; + long rc = -ENOSYS; - if ( op == MEMOP_decrease_reservation ) - return free_dom_mem(current, extent_list, nr_extents, extent_order); + if (domid == DOMID_SELF) + d = current; + else + d = find_domain_by_id(domid); - return -ENOSYS; + if (d==NULL) + return -ESRCH; + + switch( op ) + { + case MEMOP_increase_reservation: + rc = alloc_dom_mem(d, extent_list, nr_extents, extent_order); + break; + case MEMOP_decrease_reservation: + rc = free_dom_mem(d, extent_list, nr_extents, extent_order); + break; + } + + if (domid!=DOMID_SELF) + put_domain(d); + + return rc; } -- 2.30.2